\
\ 12-31-2008
\ by Victor M. <samsaga2 at gmail.com>
\

\ TODO
\ - background
\ - fonts

require sdl.fs
require gl.fs
require glf.fs
require utils.fs

640 480 2constant window-size
false constant window-fullscreen

variable window-surface
create event sdl-event% allot
variable previous-frame-ticks
variable frame-ticks-lapse
variable fps-ticks
variable fps-count
variable exit-main-loop

fvariable cube-rot 0.0e0 cube-rot f!
variable texture
variable cube-dl

: initialize-sdl
    cr
    ." Initializing SDL... "
    SDL_INIT_VIDEO sdl-init 0< if abort" initializing SDL" then
    ." ok" cr
;

: resize-window
    0 0 window-size gl-viewport

    \ projection matrix
    GL_PROJECTION gl-matrix-mode
    gl-load-identity

    45.0e0 \ fovy
    window-size swap n>f n>f f/ \ aspect ratio
    0.1e0 100.0e0 \ znear zfar
    glu-perspective

    \ modelview matrix
    GL_MODELVIEW gl-matrix-mode
    gl-load-identity
;

: create-window
    SDL_GL_DOUBLEBUFFER 1 sdl-gl-set-attribute
    
    ." Creating window... "
    SDL_OPENGL
    SDL_GL_DOUBLEBUFFER or
    SDL_HWPALETTE or
    window-fullscreen if SDL_FULLSCREEN or then
    window-size rot 32 swap
    sdl-set-video-mode
    
    dup window-surface !

    s" 3d demo0" c-string 0 sdl-wm-set-caption
    
    0< if abort" creating window" then
    ." ok" cr

    resize-window
;

: initialize-gl
    GL_SMOOTH gl-shade-model
    0.3e0 0.3e0 0.3e0 0.5e0 gl-clear-color
    1.0e0 gl-clear-depth
    GL_DEPTH_TEST gl-enable
    GL_LEQUAL gl-depth-func
    GL_PERSPECTIVE_CORRECTION_HINT GL_NICEST gl-hint
    GL_TEXTURE_2D gl-enable
;

: setup-lights
    GL_LIGHT1 GL_AMBIENT  0.5e0 0.5e0 0.5e0 1.0e0 glf-light4f
    GL_LIGHT1 GL_DIFFUSE  1.0e0 1.0e0 1.0e0 1.0e0 glf-light4f
    GL_LIGHT1 GL_POSITION 0.0e0 0.0e0 2.0e0 1.0e0 glf-light4f
    GL_LIGHT1 gl-enable
    GL_LIGHTING gl-enable
;

: setup-fps
    previous-frame-ticks @ fps-ticks !
    0 fps-count !
;

: setup-frame-ticks
    sdl-get-ticks previous-frame-ticks !
;

: setup-textures
    s" box.bmp0" c-string sdl-load-bmp
    dup 0= if abort" Error loading image" then >r
    
    1 texture gl-gen-textures
    GL_TEXTURE_2D texture gl-bind-texture

    GL_TEXTURE_2D 0 3
    r@ sdl-surface-w @
    r@ sdl-surface-h @
    0 GL_BGR
    GL_UNSIGNED_BYTE
    r@ sdl-surface-pixels @
    gl-tex-image-2d

    GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_LINEAR_MIPMAP_NEAREST gl-tex-parameter-i
    GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_NEAREST gl-tex-parameter-i

    GL_TEXTURE_2D 3
    r@ sdl-surface-w @
    r@ sdl-surface-h @
    GL_BGR
    GL_UNSIGNED_BYTE
    r@ sdl-surface-pixels @
    glu-build-2d-mipmaps

    r> sdl-free-surface
;

: initialize
    initialize-sdl
    create-window
    initialize-gl
    setup-lights
    setup-textures
    setup-fps
    setup-frame-ticks
    0 cube-dl !
;

: unitialize
    sdl-quit
;

: update-frame-ticks
    sdl-get-ticks dup previous-frame-ticks @ - swap previous-frame-ticks !
    frame-ticks-lapse !
;

: update-fps
    previous-frame-ticks @ fps-ticks @ - 1000 > if
	fps-count @ . ." fps" cr
	0 fps-count !
	previous-frame-ticks @ fps-ticks !
    else
	fps-count @ 1+ fps-count !
    then
;

: poll-events
    begin
	event sdl-poll-event
    while
	    event sdl-event-type c@
	    case
		sdl-event-quit of exit-main-loop on endof
	    endcase
    repeat
;

: scene{
    GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT or gl-clear
;

: }scene
    gl-flush
    sdl-gl-swap-buffers
;

: draw-cube
    GL_QUADS gl-begin
    0.0e0 0.0e0 1.0e0 gl-normal-3f
    0.0e0 0.0e0 gl-tex-coord-2f -1.0e0 -1.0e0  1.0e0 gl-vertex-3f
    1.0e0 0.0e0 gl-tex-coord-2f  1.0e0 -1.0e0  1.0e0 gl-vertex-3f
    1.0e0 1.0e0 gl-tex-coord-2f  1.0e0  1.0e0  1.0e0 gl-vertex-3f
    0.0e0 1.0e0 gl-tex-coord-2f -1.0e0  1.0e0  1.0e0 gl-vertex-3f
    
    0.0e0 0.0e0 -1.0e0 gl-normal-3f
    1.0e0 0.0e0 gl-tex-coord-2f -1.0e0 -1.0e0 -1.0e0 gl-vertex-3f
    1.0e0 1.0e0 gl-tex-coord-2f -1.0e0  1.0e0 -1.0e0 gl-vertex-3f
    0.0e0 1.0e0 gl-tex-coord-2f  1.0e0  1.0e0 -1.0e0 gl-vertex-3f
    0.0e0 0.0e0 gl-tex-coord-2f  1.0e0 -1.0e0 -1.0e0 gl-vertex-3f
    
    0.0e0 1.0e0 0.0e0 gl-normal-3f
    0.0e0 1.0e0 gl-tex-coord-2f -1.0e0  1.0e0 -1.0e0 gl-vertex-3f
    0.0e0 0.0e0 gl-tex-coord-2f -1.0e0  1.0e0  1.0e0 gl-vertex-3f
    1.0e0 0.0e0 gl-tex-coord-2f  1.0e0  1.0e0  1.0e0 gl-vertex-3f
    1.0e0 1.0e0 gl-tex-coord-2f  1.0e0  1.0e0 -1.0e0 gl-vertex-3f
    
    0.0e0 -1.0e0 0.0e0 gl-normal-3f
    1.0e0 1.0e0 gl-tex-coord-2f -1.0e0 -1.0e0 -1.0e0 gl-vertex-3f
    0.0e0 1.0e0 gl-tex-coord-2f  1.0e0 -1.0e0 -1.0e0 gl-vertex-3f
    0.0e0 0.0e0 gl-tex-coord-2f  1.0e0 -1.0e0  1.0e0 gl-vertex-3f
    1.0e0 0.0e0 gl-tex-coord-2f -1.0e0 -1.0e0  1.0e0 gl-vertex-3f

    1.0e0 0.0e0 0.0e0 gl-normal-3f
    1.0e0 0.0e0 gl-tex-coord-2f  1.0e0 -1.0e0 -1.0e0 gl-vertex-3f
    1.0e0 1.0e0 gl-tex-coord-2f  1.0e0  1.0e0 -1.0e0 gl-vertex-3f
    0.0e0 1.0e0 gl-tex-coord-2f  1.0e0  1.0e0  1.0e0 gl-vertex-3f
    0.0e0 0.0e0 gl-tex-coord-2f  1.0e0 -1.0e0  1.0e0 gl-vertex-3f
    
    -1.0e0 0.0e0 0.0e0 gl-normal-3f
    0.0e0 0.0e0 gl-tex-coord-2f -1.0e0 -1.0e0 -1.0e0 gl-vertex-3f
    1.0e0 0.0e0 gl-tex-coord-2f -1.0e0 -1.0e0  1.0e0 gl-vertex-3f
    1.0e0 1.0e0 gl-tex-coord-2f -1.0e0  1.0e0  1.0e0 gl-vertex-3f
    0.0e0 1.0e0 gl-tex-coord-2f -1.0e0  1.0e0 -1.0e0 gl-vertex-3f
    gl-end
;

: render-cube
    cube-dl @ not if
	." Creating display list... "
	glf-list{
	    draw-cube
	}glf-list cube-dl !
	." ok" cr
    then
    
    GL_TEXTURE_2D texture gl-bind-texture
    
    gl-load-identity
    0.0e0 0.0e0 -5.0e0 gl-translate-f
    cube-rot f@ 1.0e0 1.2e0 1.4e0 gl-rotate-f
    cube-dl @ gl-call-list
;

: render-scene ( ticks -- )
    10.0e0 f/ cube-rot f@ f+ cube-rot f!
    render-cube
;

: main-loop
    exit-main-loop off
    begin
	poll-events
	update-frame-ticks
	
	sdl-get-app-state SDL_APPINPUTFOCUS and if
	    update-fps
	    scene{
	        frame-ticks-lapse @ s>f
	        render-scene
	    }scene
	then
	
	exit-main-loop @
    until
;

: 3ddemo
    initialize
    main-loop
    unitialize
;
